package com.cakin.javademo;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @ClassName: GroupManyToMany
 * @Description: 多字段分组，多字段求和
 * @Date: 2021/3/14
 * @Author: cakin
 */
public class GroupManyToMany {
    /**
     * 功能描述：多字段分组，单字段求和 测试
     *
     * @author cakin
     * @date 2021/3/14
     * @param args 命令行
     */
    public static void main(String[] args) {
        List<Person> users = new ArrayList<>();
        users.add(new Person("tom", "15687675434", "北京", 100l,99.0));
        users.add(new Person("tom", "15687675434", "北京", 50l,49.0));
        users.add(new Person("tom", "13654345654", "上海", 77l,76.0));
        users.add(new Person("jerry", "15976543454", "苏州", 70l,69.0));
        users.add(new Person("jerry", "15976543454", "苏州", 100l,99.0));

        // 第一步：以 name phone address 三个字段为分组字段，计算 area 的和。
        List<Person> userList = new ArrayList<>();
        users.stream().collect(Collectors
                .groupingBy(user -> new Person(user.getName(), user.getPhone(), user.getCity()), Collectors.summarizingLong(user -> user.getArea())))
                .forEach((k, v) -> {
                    k.setArea(v.getSum());
                    userList.add(k);
                });

        // 第二步：以 name phone address 三个字段为分组字段，分组计算 money 的和。
        List<Person> userList1 = new ArrayList<>();
        users.stream().collect(Collectors
                .groupingBy(user -> new Person(user.getName(), user.getPhone(), user.getCity()), Collectors.summarizingDouble(user -> user.getMoney())))
                .forEach((k, v) -> {
                    k.setMoney(v.getSum());
                    userList1.add(k);
                });

        // 第三步：将 userList1 中的 money 拷贝到 userList中
        for (int i = 0; i < userList1.size(); i++) {
            userList.get(i).setMoney(userList1.get(i).getMoney());
        }

        for (Person person : userList) {
            System.out.println(person);
        }
    }
}

/**
 * @ClassName: Person
 * @Description: person类
 * @Date: 2021/3/13
 * @Author: cakin
 */
class Person {
    /**
     * 姓名
     */
    public String name;
    /**
     * 手机
     */
    public String phone;
    /**
     * 城市
     */
    public String city;
    /**
     * 房屋面积
     */
    public Long area;

    /**
     * 房屋总价
     */
    public Double money;

    public Person(String name, String phone, String city) {
        this.name = name;
        this.phone = phone;
        this.city = city;
    }

    public Person(String name, String phone, String city, Long area,Double money) {
        this.name = name;
        this.phone = phone;
        this.city = city;
        this.area = area;
        this.money = money;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public Long getArea() {
        return area;
    }

    public void setArea(Long area) {
        this.area = area;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                ", city='" + city + '\'' +
                ", area=" + area +
                ", money=" + money +
                '}';
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, phone, city);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(name, person.name) &&
                Objects.equals(phone, person.phone) &&
                Objects.equals(city, person.city) &&
                Objects.equals(area, person.area) &&
                Objects.equals(money, person.money);
    }
}
